package com.ssy.lingxi.member.merchant.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ssy.lingxi.member.merchant.api.constant.CountryCodeEnum;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * 安全字符串工具类
 * @author 万宁
 * @version 2.0.0
 * @date 2020-07-06
 */
public class SecurityStringUtils {
    /**
     * 屏蔽关键信息的字符串
     */
    private static final String MASK_STR = "*";

    /**
     * Email的符号
     */
    private static final String EMAIL_SYMBOL = "@";

    /**
     * 短信验证码随机生成器
     */
    private static final Random RANDOM = new Random();

    public static String getBatchNo() {
        String millisecond = String.valueOf(System.currentTimeMillis());
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHMMss")).concat(millisecond.substring(millisecond.length() - 3).concat(String.valueOf(RANDOM.nextInt(10000))));
    }

    /**
     * 屏蔽手机号码中间4位
     *
     * @param countryCode 国家代码
     * @param phone       手机号码
     * @return 屏蔽字符串
     */
    public static String getMaskPhone(String countryCode, String phone) {
        if (!StringUtils.hasLength(phone)) {
            return "";
        }

        countryCode = StringUtils.hasLength(countryCode) ? countryCode : "";
        return countryCode + " " + phone.substring(0, 3) + String.join("", Collections.nCopies(4, "*")) + phone.substring(7);

        //根据国家代码进行判断，国家代码不为空
//        if (countryCode.startsWith("+86") || countryCode.startsWith("86")) {
//            return countryCode + " " + phone.replace(phone.subSequence(3,8), maskStr);
//        }
//
//        return "";
    }

    /**
     * 屏蔽邮箱地址
     *
     * @param email 邮箱地址
     * @return 屏蔽字符串
     */
    public static String getMaskMail(String email) {
        if (!StringUtils.hasLength(email) || !email.contains(EMAIL_SYMBOL)) {
            return "";
        }

        String emailAccount = email.substring(0, email.indexOf(EMAIL_SYMBOL));
        String emailDomain = email.substring(email.indexOf(EMAIL_SYMBOL));
        switch (emailAccount.length()) {
            case 0:
            case 1:
                return MASK_STR + emailDomain;
            case 2:
                return emailAccount.substring(0, 1) + MASK_STR + emailDomain;
            case 3:
            case 4:
            case 5:
                return emailAccount.substring(0, 1) + String.join("", Collections.nCopies(emailAccount.length() - 2, MASK_STR)) + emailAccount.substring(emailAccount.length() - 1) + emailDomain;
            default:
                return emailAccount.substring(0, 2) + String.join("", Collections.nCopies(emailAccount.length() - 4, MASK_STR)) + emailAccount.substring(emailAccount.length() - 2) + emailDomain;
        }
    }

    /**
     * 生成6位数字的短信验证码
     *
     * @return 短信验证码
     */
    public static String getRandomSmsCode() {
        int code = RANDOM.nextInt(1000000);
        return String.format("%06d", code);
    }

    /**
     * 将前端传递的注册资料标签，转换为List<String>
     * @param src 注册资料信息，在Map<String, Object>中的value
     * @return 如果转换成功，则返回转换结果，否则返回Null
     */
    public static List<String> convertStringToList(String src) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(src, new TypeReference<List<String>>() {
            });
        } catch (Exception e1) {
            return null;
        }
    }

    /**
     * 将前端传递的注册资料标签，转换为List<Long>
     * @param src 注册资料信息，在Map<String, Object>中的value
     * @return 如果转换成功，则返回转换结果，否则返回Null
     */
    public static List<Long> convertStringToLongList(String src) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(src, new TypeReference<List<Long>>() {
            });
        } catch (Exception e1) {
            return null;
        }
    }

    /**
     * 将前端传递的注册资料标签，转换为Long<Long>
     * @param src 注册资料信息，在Map<String, Object>中的value
     * @return 如果转换成功，则返回转换结果，否则返回Null
     */
    public static Long convertStringToLong(String src) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            if(!StringUtils.hasLength(src)) {
                return null;
            }

            return Long.parseLong(src);
        } catch (Exception e1) {
            return null;
        }
    }

    /**
     * Json反序列化单个对象
     * @param jsonStr json字符串
     * @param classOfT 对象Class
     * @param <T> 泛型参数
     * @return 对象，如果失败返回Null
     */
    public static <T> T deserializeObject(String jsonStr, Class<T> classOfT) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return mapper.readValue(jsonStr, classOfT);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Json序列化单个对象
     * @param obj Object对象
     * @return 字符串，如果失败返回空字符串
     */
    public static String serializeObject(Object obj) {
        try {
            if(obj == null) {
                return "";
            }

            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(obj);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 检查字符串是否符合yyyy-MM-dd格式
     * @param dateStr 日期字符串
     * @return 是/否
     */
    public static boolean notDateString(String dateStr) {
        final String slash = "-";
        if(!StringUtils.hasLength(dateStr) || !dateStr.contains(slash)) {
            return true;
        }

        try {
            LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        } catch (Exception e) {
            return true;
        }

        return false;
    }

    /**
     * 校验手机号码格式是否正确
     * @param codeEnum 国家代码枚举类
     * @param phone 手机号码
     * @return 格式是否正确
     */
    public static boolean checkPhone(CountryCodeEnum codeEnum, String phone) {
        if (codeEnum == CountryCodeEnum.China) {
            return checkChinaPhone(phone);
        }

        return checkPhoneByNumber(phone);
    }

    /**
     * 校验国内手机号码格式
     * @param phone 手机号码
     * @return 格式是否正确
     */
    public static boolean checkChinaPhone(String phone) {
        if(!StringUtils.hasLength(phone)) {
            return false;
        }

        String regex = "^(1[3-9]\\d{9}$)";
        return Pattern.compile(regex).matcher(phone).matches();
    }

    /**
     * 校验手机号是否由数字组成
     * @param phone 手机号码
     */
    public static boolean checkPhoneByNumber(String phone) {
        if(!StringUtils.hasLength(phone) || phone.length() > 20) {
            return false;
        }

        String regex = "^\\d+$";
        return Pattern.compile(regex).matcher(phone).matches();
    }
}
